<html>
<head><meta charset="utf-8"><title>I/O safety · t-lang/wg-unsafe-code-guidelines · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/index.html">t-lang/wg-unsafe-code-guidelines</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html">I/O safety</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="235889697"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235889697" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235889697">(Apr 23 2021 at 18:42)</a>:</h4>
<p>Hello! I'm working towards an RFC proposing to treat raw file descriptors more like how Rust treats raw pointers, with a concept of "I/O safety". If anyone here is interested in what this looks like, the current draft is <a href="https://github.com/sunfishcode/rfcs/blob/main/text/0000-io-safety.md">here</a>. Feedback welcome!</p>



<a name="235904927"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235904927" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235904927">(Apr 23 2021 at 20:37)</a>:</h4>
<p>Not really a fan. IMO, <code>unsafe</code> referring only to operations that cause memory/thread safety problems (and fwiw, thread safety is necessary for memory safety, so these go together) is a good thing. IMO inventing a library-level concept of safety and using <code>unsafe</code> for it is an antipattern</p>



<a name="235906248"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235906248" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235906248">(Apr 23 2021 at 20:48)</a>:</h4>
<p>As long as IO safety doesn't ever interact with memory safety, it seems mostly harmless. But it seems much more likely that holes in the IO safety promise will be caused by people who don't know about IO safety and reason that file descriptors are just integers. So the main danger for memory safety is if this new promise is used in some way that elevates an IO soundness bug to a memory soundness bug. It's not clear to me if this is possible, perhaps if you had an array indexed by file descriptors and associate mutable borrows to all the open files?</p>



<a name="235907343"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235907343" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> oliver <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235907343">(Apr 23 2021 at 20:58)</a>:</h4>
<p>'as long as doesn't ever' has a nice ring to it <span aria-label="laughing" class="emoji emoji-1f606" role="img" title="laughing">:laughing:</span></p>



<a name="235926327"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235926327" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235926327">(Apr 24 2021 at 00:15)</a>:</h4>
<p>I'd argue that file-descriptor/win32-handle safety <em>is</em> related to memory safety: if you have one thread opening, then <code>mmap</code>ping a file (e.g. the dynamic linker or posix ipc named semaphores), another thread could close that file descriptor and replace it with a new file descriptor, which is then <code>mmap</code>ed by the first thread and used from code that assumes the mapped memory is correct, violating memory safety.</p>



<a name="235926436"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235926436" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235926436">(Apr 24 2021 at 00:17)</a>:</h4>
<p><a href="https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/pthread/sem_open.c;h=0265abc45bbedf35eb56564c2a6cdb2811b20037;hb=HEAD#l31">https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/pthread/sem_open.c;h=0265abc45bbedf35eb56564c2a6cdb2811b20037;hb=HEAD#l31</a></p>



<a name="235928908"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235928908" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235928908">(Apr 24 2021 at 00:59)</a>:</h4>
<p>doing anything with mmap is known to be unsafe regardless of whatever safety rules are assigned to file descriptors</p>



<a name="235947176"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235947176" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hyd-dev <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235947176">(Apr 24 2021 at 06:38)</a>:</h4>
<p>I think at least Windows <code>HANDLE</code> safety is important: when using IOCP, I would like to assume the <code>lpOverlapped</code> pointer filled by <code>GetQueuedCompletionStatus()</code> is valid as a pointer to a custom, library-specific <code>OVERLAPPED</code> extension structure or has a known special value like null. If there's no <code>HANDLE</code> safety, anyone can "safely" use <code>PostQueuedCompletionStatus()</code> or other I/O functions to post any (invalid) pointer, which will break my assumption.</p>
<p>By "<code>OVERLAPPED</code> extension structure" I mean something like this:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="cp">#[repr(C)]</span><span class="w"></span>
<span class="k">struct</span> <span class="nc">Foo</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="n">header</span>: <span class="nc">OVERLAPPED</span><span class="p">,</span><span class="w"></span>
<span class="w">    </span><span class="n">extra_data_like_waker</span>: <span class="nc">std</span>::<span class="n">task</span>::<span class="n">Waker</span><span class="p">,</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>I also have an example that relies on Unix file descriptor safety, but I feel like such code needs to be written deliberately and don't know if it's a problem in practice: <a href="https://github.com/rust-lang/socket2/issues/218#issue-857177297">https://github.com/rust-lang/socket2/issues/218#issue-857177297</a></p>



<a name="235947446"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235947446" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235947446">(Apr 24 2021 at 06:44)</a>:</h4>
<p>ah, yeah, i've done such things with IOCP before (that's sort of how you have to use it, IIRC). that said, i think the unsafety there is encapsulated in the unsafe IOCP functions, no?</p>



<a name="235947480"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235947480" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235947480">(Apr 24 2021 at 06:45)</a>:</h4>
<p>more broadly, I think the bar for adding a new concept of safety to rust should be very high, honestly.</p>
<p>as violating this is considered undefined behavior on the same order of memory safety, i feel like there's no way that introducing this could do anything other than lead to <em>more</em> unsafe code in the wild, which is currently soundly written without unsafe.</p>



<a name="235950260"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235950260" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hyd-dev <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235950260">(Apr 24 2021 at 07:38)</a>:</h4>
<p><span class="user-mention silent" data-user-id="209168">Thom Chiovoloni</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/235947446">said</a>:</p>
<blockquote>
<p>ah, yeah, i've done such things with IOCP before (that's sort of how you have to use it, IIRC). that said, i think the unsafety there is encapsulated in the unsafe IOCP functions, no?</p>
</blockquote>
<p>I'm worrying that someone might create a safe binding of something like <code>PostQueuedCompletionStatus()</code>, if they assume "doing anything with any <code>HANDLE</code> is safe". Windows itself does not require any other parameter of <code>PostQueuedCompletionStatus()</code> to be valid ("The system does not use or validate these values. In particular, the <code>lpOverlapped</code> parameter need not point to an <code>OVERLAPPED</code> structure."), so they might assume passing anything (including any <code>HANDLE</code>) to <code>PostQueuedCompletionStatus()</code> is safe.</p>



<a name="235950536"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235950536" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235950536">(Apr 24 2021 at 07:44)</a>:</h4>
<blockquote>
<p>if they assume "doing anything with any HANDLE is safe". </p>
</blockquote>
<p>This feels a bit ridiculous, since obviously it's not. Anyway, this is a normal memory safety concern, and doesn't require the introduction of a new concept of I/O safety to declare such a binding unsound.</p>



<a name="235950762"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235950762" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hyd-dev <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235950762">(Apr 24 2021 at 07:48)</a>:</h4>
<p>My impression is that "I/O safety" is used to prevent the "doing anything with any <code>HANDLE</code> is safe" assumption.</p>



<a name="235950980"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235950980" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> hyd-dev <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235950980">(Apr 24 2021 at 07:53)</a>:</h4>
<p>I don't object to unifying that kind of safety with memory safety, though.</p>



<a name="235958966"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235958966" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235958966">(Apr 24 2021 at 10:07)</a>:</h4>
<p><span class="user-mention silent" data-user-id="209168">Thom Chiovoloni</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/235928908">said</a>:</p>
<blockquote>
<p>doing anything with mmap is known to be unsafe regardless of whatever safety rules are assigned to file descriptors</p>
</blockquote>
<p>I think it should be possible to have safe wrappers around <code>mmap</code></p>



<a name="235959070"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235959070" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235959070">(Apr 24 2021 at 10:09)</a>:</h4>
<p><span class="user-mention silent" data-user-id="209168">Thom Chiovoloni</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/235904927">said</a>:</p>
<blockquote>
<p>Not really a fan. IMO, <code>unsafe</code> referring only to operations that cause memory/thread safety problems (and fwiw, thread safety is necessary for memory safety, so these go together) is a good thing. IMO inventing a library-level concept of safety and using <code>unsafe</code> for it is an antipattern</p>
</blockquote>
<p>you just called <code>NonZero*</code> an antipattern, didnt you?<br>
Rust has plenty of library-level safety concepts and they are a crucial part of Rust's overall story of safe and efficient abstractions</p>



<a name="235959081"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235959081" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235959081">(Apr 24 2021 at 10:09)</a>:</h4>
<p>without this notion of "I/O safety", it is <em>impossible</em> to build such kinds of abstractions around file descriptors</p>



<a name="235975878"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235975878" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Steven Fackler <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235975878">(Apr 24 2021 at 14:54)</a>:</h4>
<p>I don't see the NonZero type as being "library level unsafe" at all since the nonzeroness is actually exploited by the compiler.</p>



<a name="235975907"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235975907" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Steven Fackler <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235975907">(Apr 24 2021 at 14:55)</a>:</h4>
<p>str's utf8 validity is a better example there IMO</p>



<a name="235984590"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235984590" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235984590">(Apr 24 2021 at 16:49)</a>:</h4>
<p>Hm, fair.</p>



<a name="235984687"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235984687" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235984687">(Apr 24 2021 at 16:50)</a>:</h4>
<p>Any kind of type system trickery involving user-defined invariants would fall under this -- e.g., type-based "taint tracking"</p>



<a name="235991535"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235991535" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235991535">(Apr 24 2021 at 18:14)</a>:</h4>
<p>str's utf8 validity can lead to actual memory unsafety if misused. if it couldn't, I'd consider it an antipattern</p>



<a name="235994486"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235994486" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235994486">(Apr 24 2021 at 18:43)</a>:</h4>
<p>I have a pair of traits in my chrono library, <code>TrivialClock</code> and <code>Monotonic</code>. Both are unsafe, and define the preconditions on implementations: <code>TrivialClock</code> states that if <code>T: TrivialClock</code>, then <code>&lt;T as Clock&gt;::now()</code> will not panic, <code>Monotonic</code> states that if the statement<code>let t1 = &lt;T as Clock&gt;::now();</code> <em>happens-before</em> the statement <code>let t2 = &lt;T as Clock&gt;::now();</code>, then <code>t1&lt;=t2</code> is true. Would you say that either of these traits are that same antipattern? I myself consider it an incorrect to express a guarantee in the typesystem that cannot be relied upon.</p>



<a name="235994989"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235994989" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235994989">(Apr 24 2021 at 18:48)</a>:</h4>
<p>Yes, as I find using <code>unsafe</code> as a way to express correctness invariants to be an antipattern. If you use the happens-before logic in multithreaded code, I wouldn't say it's the antipattern (although I might consider it to be a dubious application of unsafe).</p>



<a name="235995817"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235995817" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Connor Horman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235995817">(Apr 24 2021 at 18:57)</a>:</h4>
<p>Interestingly, the result of not being unsafe means that you could never assume the semantic behaviour of the trait, thus is equivalent to only it's syntactic guarantees (In C++, this is the distinction between <em>satisfying</em> a trait and <em>modelling</em> it; everywhere a trait is used in the standard library, an implicit precondition is that the type <em>models</em> that concept). <br>
In fact, the advantage of the <code>TrivialClock</code> trait is that it can be used to optimize <code>unsafe</code> code by assuming no panics occur, because <code>TrivialClock</code> guarantees it.  <br>
Coming from C++, I find a distinction between "I guarantee this behaviour" and "I guarantee this behaviour, but only to safe code" incredibly limiting (An example of this, it's actually incorrect to rely on the <em>guaranteed</em> property of <code>Fuse</code> in unsafe code because it uses the non-<code>unsafe</code> FusedIterator trait to optimize). In C++, if you say you are a monotonic clock, then anything can (and may just) rely upon that statement being true.</p>



<a name="235995884"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235995884" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235995884">(Apr 24 2021 at 18:58)</a>:</h4>
<p><span class="user-mention silent" data-user-id="257758">Connor Horman</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/235994486">said</a>:</p>
<blockquote>
<p>I myself consider it an incorrect to express a guarantee in the typesystem that cannot be relied upon.</p>
</blockquote>
<p>I think the important part here is the distinction between "relied upon <em>for memory safety</em>" and "relied upon <em>for meaningful output</em>".</p>
<p>Are you depending on that <em>happens-before</em> property for memory safety ever?  Or is it just like how <code>sort</code> will only sort things meaningfully if your <code>Ord</code> meets the usual rules, but you still don't need to <code>unsafe impl Ord</code> to use <code>sort</code> -- and <code>sort</code> thus needs to be memory-safe regardless of what (memory-safe) things <code>Ord</code> does.</p>



<a name="235996813"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235996813" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235996813">(Apr 24 2021 at 19:08)</a>:</h4>
<p>It seems certainly plausible that one might rely on clock monotonicity for memory safety, just like it is plausible to rely on a well-behaved ordering function for memory safety. <code>Ord</code> would be the wrong trait for that, we'd need <code>TrustedOrd</code>, but there's no "antipattern" in doing that, I'd say.</p>



<a name="235996950"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235996950" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235996950">(Apr 24 2021 at 19:10)</a>:</h4>
<p>so IMO it is perfectly reasonable and not at all an antipattern to use <code>unsafe</code> in such a situation.<br>
judging if something is used for memory safety requires infinite foresight: <em>any</em> invariant could become crucial for memory safety under the right conditions. including FD privacy.<br>
so, declaring user invariants as "safety invariants" of the type, and making it <code>unsafe</code> to violate them, is not an antipattern at all, IMO -- to the contrary: I'd call this a <em>good</em> way to use the Rust type system; I'd call desparately <em>avoiding</em> this an antipattern.</p>



<a name="235997289"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235997289" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235997289">(Apr 24 2021 at 19:14)</a>:</h4>
<p>Sometimes people mean different things when they say things like "unsafe is for memory safety only", so let me clarify: <code>mem::forget</code> should <em>not</em> be marked <code>unsafe</code>. I am mentioning this because the words "unsafe is for memory safety only" were used in that argument. But the thing is, making <code>mem::forget</code> <code>unsafe</code> would <em>not</em> give user invariants any extra power: one can implement a function that is observably equivalent to <code>mem::forget</code> entirely in safe code using <code>Rc</code>. So, using <code>unsafe</code> here would be quite clearly an antipattern.<br>
That is, however, a very different situation from what we are discussing above.  What we are discussing is: are there conceivable situations where a library would (possibly through composition with other libraries) rely on FD privacy for memory safety? I'd say "definitely yes", and hence messing with FDs you dont own <em>needs to be</em> <code>unsafe</code>. In other words, making "raw FD manipulation" <code>unsafe</code> <em>does</em> give user invariants extra power.</p>



<a name="235999139"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/235999139" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#235999139">(Apr 24 2021 at 19:39)</a>:</h4>
<p>I think you've misinterpreted me — I'm definitely not saying TrustedOrd would be an antipattern, but I also think that there should be a higher barrier to adding such things.</p>
<p>I'm willing to concede that perhaps that barrier is met for I/O, although I'm not entirely convinced it is, and it's unclear to me that it's worth the pain this adds. For what it's worth, I don't feel that "doubling down" on from_raw_fd being unsafe is the right call — it feels like the other direction should be the one we go in.</p>
<p>But, I also don't care enough about this to fight about it more.</p>



<a name="236007894"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236007894" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236007894">(Apr 24 2021 at 21:17)</a>:</h4>
<p><span class="user-mention" data-user-id="120791">@RalfJ</span> Mmap is unsafe as any other process may truncate the backing file and thus cause the mapping to shrink. This can't be avoided without mandatory locks, which only exist on some OSes.</p>



<a name="236033472"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236033472" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236033472">(Apr 25 2021 at 03:32)</a>:</h4>
<p><span class="user-mention silent" data-user-id="209168">Thom Chiovoloni</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/235991535">said</a>:</p>
<blockquote>
<p>str's utf8 validity can lead to actual memory unsafety if misused. if it couldn't, I'd consider it an antipattern</p>
</blockquote>
<p>This claim is repeated a lot but my attempt to <a href="#narrow/stream/122651-general/topic/Memory.20safety.20exploits.20involving.20non-UTF-8.20strings">find examples</a> of such a thing came up empty. It seems the only reason utf8 invalidity can turn into memory unsafety is the self-supporting reason that because it is documented as a library invariant, external crates might potentially take advantage of it and elevate it to a memory safety issue.</p>



<a name="236033705"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236033705" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236033705">(Apr 25 2021 at 03:37)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133247">bjorn3</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/236007894">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> Mmap is unsafe as any other process may truncate the backing file and thus cause the mapping to shrink. This can't be avoided without mandatory locks, which only exist on some OSes.</p>
</blockquote>
<p>This sounds like a "<code>gets()</code> is unsafe under all conditions" type of issue. Has there been any linux kernel work done to address this issue? Because this is pretty damning. I would hope that this can be resolved by either locking the file like you suggest, or by migrating the memory map to a copy if the backing file is modified or truncated.</p>



<a name="236035870"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236035870" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236035870">(Apr 25 2021 at 04:19)</a>:</h4>
<p>well, in theory you just have to handle the SIGBUS (sometimes SIGSEGV, not sure which linux emits for this). It's a very different kind of "always unsafe" than gets()</p>



<a name="236036083"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236036083" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236036083">(Apr 25 2021 at 04:22)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/236033472">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="209168">Thom Chiovoloni</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/235991535">said</a>:</p>
<blockquote>
<p>str's utf8 validity can lead to actual memory unsafety if misused. if it couldn't, I'd consider it an antipattern</p>
</blockquote>
<p>This claim is repeated a lot but my attempt to <a href="#narrow/stream/122651-general/topic/Memory.20safety.20exploits.20involving.20non-UTF-8.20strings">find examples</a> of such a thing came up empty. It seems the only reason utf8 invalidity can turn into memory unsafety is the self-supporting reason that because it is documented as a library invariant, external crates might potentially take advantage of it and elevate it to a memory safety issue.</p>
</blockquote>
<p>You were looking for exploitable problems, I believe. It's trivial to find &lt;=3 byte out of bounds reads and writes caused by it, which are certainly memory unsafe.</p>
<p>It's just hard to make those cause actual problems in practice. I mentioned some thoughts at the end of <a href="#narrow/stream/122651-general/topic/Memory.20safety.20exploits.20involving.20non-UTF-8.20strings/near/234360457">https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/Memory.20safety.20exploits.20involving.20non-UTF-8.20strings/near/234360457</a> though, I suspect using <code>&amp;mut String</code> methods would be how.</p>



<a name="236036224"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236036224" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236036224">(Apr 25 2021 at 04:25)</a>:</h4>
<p><span class="user-mention silent" data-user-id="209168">Thom Chiovoloni</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/236035870">said</a>:</p>
<blockquote>
<p>well, in theory you just have to handle the SIGBUS (sometimes SIGSEGV, not sure which linux emits for this). It's a very different kind of "always unsafe" than gets()</p>
</blockquote>
<p>Isn't "the data can possibly change from what was last there without your involvement, and may also throw a signal error" exactly the claim that you get from reading random memory? (Of course the compiler has to be on board with the access or else UB can cause much worse issues.)</p>



<a name="236039347"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236039347" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236039347">(Apr 25 2021 at 05:26)</a>:</h4>
<p>gets allows attacker controlled writes, which is the problem with it. that said, i'd definitely be in favor for ways to make mmap more usable. even if you do handle sigbus in practice it's a huge headache</p>



<a name="236044759"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236044759" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jacob Lifshay <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236044759">(Apr 25 2021 at 07:06)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133247">bjorn3</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/236007894">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> Mmap is unsafe as any other process may truncate the backing file and thus cause the mapping to shrink. This can't be avoided without mandatory locks, which only exist on some OSes.</p>
</blockquote>
<p>That's not actually the case for all file-like things: iirc Linux's memoryfd can be set to a fixed non-truncatable length. I'd expect posix semaphores to be built on something like that, though I haven't checked.</p>



<a name="236058930"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236058930" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236058930">(Apr 25 2021 at 11:34)</a>:</h4>
<p>Linux's <code>create_memfd</code> is a good example. It gives you an anonymous open file which seems like it ought to let you <code>mmap</code> and pass <code>&amp;[u8]</code>s to safe Rust.  But without I/O safety, someone else in the process could accidentally <code>ftruncate</code> or <code>write</code> it, breaking memory safety.</p>



<a name="236066972"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236066972" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236066972">(Apr 25 2021 at 13:48)</a>:</h4>
<p>That's a pretty good example; different from the classic <em>shared</em> <code>mmap</code> examples, since only the current process can sanely interact with that fd. But I see that <a href="https://doc.rust-lang.org/std/os/unix/io/trait.FromRawFd.html">https://doc.rust-lang.org/std/os/unix/io/trait.FromRawFd.html</a> is already <code>unsafe</code>, so what else should be affected to allow that <code>create_memfd</code> abstraction to be marked non-<code>unsafe</code>?</p>
<hr>
<p>To me, there is a practical difference between somebody misusing <code>FromRawFd</code> and causing UB in the non-<code>unsafe</code> abstraction around <code>create_memfd</code> (or private <code>mmap</code>) ; and somebody misusing <code>/proc/…</code> pseudo-files, such as <code>/proc/…/fd/${fd}</code>. That may  just be me, but in the former case, there is a direct interaction with handles seen by the process, and in the latter case there is special OS magic that allows any process to "intro/inter-spect" these internal handles and the raw memory behind them.</p>



<a name="236076075"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236076075" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236076075">(Apr 25 2021 at 16:16)</a>:</h4>
<p><span class="user-mention silent" data-user-id="232018">Daniel Henry-Mantilla</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/236066972">said</a>:</p>
<blockquote>
<p>That's a pretty good example; different from the classic <em>shared</em> <code>mmap</code> examples, since only the current process can sanely interact with that fd. But I see that <a href="https://doc.rust-lang.org/std/os/unix/io/trait.FromRawFd.html">https://doc.rust-lang.org/std/os/unix/io/trait.FromRawFd.html</a> is already <code>unsafe</code>, so what else should be affected to allow that <code>create_memfd</code> abstraction to be marked non-<code>unsafe</code>?</p>
</blockquote>
<p><code>from_raw_fd</code> being unsafe does indeed cover most of it. However, <a href="https://github.com/sunfishcode/rfcs/blob/main/text/0000-io-safety.md#motivation">there's a loophole</a> I'm working on a proposal to close.</p>
<blockquote>
<p>To me, there is a practical difference between somebody misusing <code>FromRawFd</code> and causing UB in the non-<code>unsafe</code> abstraction around <code>create_memfd</code> (or private <code>mmap</code>) ; and somebody misusing <code>/proc/…</code> pseudo-files, such as <code>/proc/…/fd/${fd}</code>. That may  just be me, but in the former case, there is a direct interaction with handles seen by the process, and in the latter case there is special OS magic that allows any process to "intro/inter-spect" these internal handles and the raw memory behind them.</p>
</blockquote>
<p>I agree. I/O safety is just about handles seen by the process.</p>



<a name="236093809"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236093809" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236093809">(Apr 25 2021 at 21:06)</a>:</h4>
<p>...oh lol, I thought RawFd was a struct wrapping a c_int, not <em>literally a c_int</em>.</p>



<a name="236094281"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236094281" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236094281">(Apr 25 2021 at 21:12)</a>:</h4>
<p>Yeah, that's unfortunate</p>



<a name="236160551"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236160551" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236160551">(Apr 26 2021 at 11:59)</a>:</h4>
<p><span class="user-mention silent" data-user-id="133247">bjorn3</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/236007894">said</a>:</p>
<blockquote>
<p><span class="user-mention silent" data-user-id="120791">RalfJ</span> Mmap is unsafe as any other process may truncate the backing file and thus cause the mapping to shrink. This can't be avoided without mandatory locks, which only exist on some OSes.</p>
</blockquote>
<p>AFAIK there are ways to mmap "private files" that dont have names in a global filesystem namespace and thus cannot be truncated by other processes (either because they dont exist as real files to begin with, or because something external to the Rust progress, like some container environment, is ensuring isolation).<br>
I guess <code>create_memfd</code> is what I was thinking of.</p>



<a name="236161397"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236161397" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> tm <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236161397">(Apr 26 2021 at 12:05)</a>:</h4>
<p>Another example would be a running executable, which cannot be modified on some OSes.</p>



<a name="236210637"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236210637" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> comex <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236210637">(Apr 26 2021 at 17:15)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/236036224">said</a>:</p>
<blockquote>
<p>Isn't "the data can possibly change from what was last there without your involvement, and may also throw a signal error" exactly the claim that you get from reading random memory? (Of course the compiler has to be on board with the access or else UB can cause much worse issues.)</p>
</blockquote>
<p>From a low-level perspective, more or less.  But reading random memory is like picking a <em>random</em> file and reading from it.  In both cases, it's not unsafe per se just to do the read, but if you're planning on displaying the results to the user, you run the risk of accidentally disclosing secrets.  In contrast, if you mmap a specific file and display its contents – well, presumably you meant to disclose the contents of that file, and if someone else sticks secrets in there, it's their fault.</p>



<a name="236210929"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236210929" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> comex <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236210929">(Apr 26 2021 at 17:17)</a>:</h4>
<p>Also, while it's not common, it's possible to mmap hardware MMIO registers directly into a user process's address space.  In that case, a stray read could potentially have side effects, although most modern hardware is designed so that MMIO reads don't have side effects.</p>



<a name="236308155"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236308155" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Elichai Turkel <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236308155">(Apr 27 2021 at 09:36)</a>:</h4>
<p><span class="user-mention silent" data-user-id="209168">Thom Chiovoloni</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/235994989">said</a>:</p>
<blockquote>
<p>Yes, as I find using <code>unsafe</code> as a way to express correctness invariants to be an antipattern. If you use the happens-before logic in multithreaded code, I wouldn't say it's the antipattern (although I might consider it to be a dubious application of unsafe).</p>
</blockquote>
<p>wait, so if they add in some other code <code>if t1&gt;t2 {hint::unreachable_unchecked()}</code> then now the unsafe impl is justified? where does the line draws exactly? (I would accept drawing the line in "miri should be able to catch violations of the "safety" invariant")</p>



<a name="236371956"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236371956" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236371956">(Apr 27 2021 at 16:51)</a>:</h4>
<p>I believe that this extension may be justified, but also, I believe that unsafe code must in the end fundamentally depend on safe code to be implemented correctly as well. All the world falls down if 2 * 4 != 8, and as Ralf said, anything can wind up being an invariant. The detail should not be that safe code is "allowed to be evil", but that safe code should be possible to be "automatically correct", at least w/r/t memory-safety.</p>



<a name="236375256"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236375256" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236375256">(Apr 27 2021 at 17:14)</a>:</h4>
<p>To me, an <code>unsafe</code> block is an unchecked introduction of an assumed-true premise. Any other block of code is a logical extrapolation from those assumptions. But if you try to write a logical extension and you write it inaccurately, you still can reach the wrong conclusion. A premise can be partially grounded on previous conclusions. In that case, a flaming train wreck can arise because of those inaccurate conclusions. There is nothing to help it though at that point. Your logic is equally undermined whether the inaccuracy happened to be in an unsafe or safe block.</p>
<p>So an <code>unsafe</code> impl should represent, to me, that the premise <em>arrives</em>, at least in part, from Beyond Rust. Things interacting with the OS on certain levels are quite possibly appropriate here. But just because "something could go awry if the logic is wrong" is not sufficient. That will always be with us.</p>



<a name="236957078"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236957078" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236957078">(May 01 2021 at 10:41)</a>:</h4>
<p>There's now also an IRLO thread: <a href="https://internals.rust-lang.org/t/pre-rfc-i-o-safety/14585">https://internals.rust-lang.org/t/pre-rfc-i-o-safety/14585</a></p>



<a name="236957176"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236957176" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236957176">(May 01 2021 at 10:43)</a>:</h4>
<p>It's not about whether and to what extend things could go awry -- on a very technical level, this is about the kind of vocabulary that is available to types as part of their safety invariant. I/O safety is a prerequisite to allow these invariants to talk about "ownership of I/O handles" and to make any kind of claim about what happens when interacting with an I/O handle.</p>



<a name="236957179"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/236957179" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#236957179">(May 01 2021 at 10:44)</a>:</h4>
<p>Quoting myself from that thread:</p>
<blockquote>
<p>What it does is it makes the "underlying logic in which Rust types can express invariants" more powerful, it adds some new vocabulary -- Rust type invariants can (and do) already refer to the concept of "owning/borrowing a piece of memory"; now they can also be "owning/borrowing an I/O handle". This logic, however, is not described anywhere in the Rust documentation. (We proposed one possible such logic in the RustBelt work. Sadly, this work is not very accessible to non-researchers, so it is not at all clear how to even have a reasonable discussion about "officially" picking one possible logic as the one that Rust will use -- and given the requirements for a "logic of Rust invariants", I do not have good ideas for how to improve that situation.)</p>
</blockquote>



<a name="238543690"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238543690" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238543690">(May 12 2021 at 21:00)</a>:</h4>
<p>@RalfJung I'm ultimately ok with either approach to <code>IoSafe</code>, since I/O safety itself is the bigger goal, so I've now updated the draft to describe <code>RalfIoSafe</code> instead.</p>



<a name="238543915"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238543915" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238543915">(May 12 2021 at 21:01)</a>:</h4>
<p>That said, I'm still unclear on the motivation for <code>RalfIoSafe</code>, so if you don't mind taking some time to answer a few more questions, I'd be grateful.</p>
<blockquote>
<p>We do <em>not</em> have any trait on the "memory safety" side that corresponds to <code>AsRawFd+DanIoSafe</code>, which makes it hard for me to imagine a situation where this guarantee is needed.</p>
</blockquote>
<p>We have something very close: <code>(&amp;x[..]).as_ptr()</code>. That's generic over data structures which implement a trait, and returns a pointer not connected to any static lifetime. Dereferencing the pointer depends only on pointer aliasing rules and the pointee. That's the analog the what <code>AsRawFd+DanIoSafe</code> is doing. As you discussed earlier, it's probably <em>very</em> error-prone to use this pointer outside the scope of <code>&amp;self</code>. But it's not <em>invalid</em>.</p>
<p>The idea of introducing borrowing rules without static enforcement seems to me unprecedented. I'm not aware of anything in Rust, or any other language, which works like that.</p>
<p>I don't think <code>DanIoSafe</code> is inherently great, or even a practical necessity. But it feels closest to fitting within how Rust already works.</p>



<a name="238630375"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238630375" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238630375">(May 13 2021 at 14:40)</a>:</h4>
<blockquote>
<p>We have something very close: (&amp;x[..]).as_ptr(). </p>
</blockquote>
<p>We have the <em>method</em> <code>as_ptr</code>, but we don't have a <em>trait</em> abstracting over it. That makes all the difference in the world, so it is not at all an analog to <code>AsRawFd+DanIoSafe</code>.<br>
I feel I said that multiple times already so I am clearly not expressing myself very well, but I am also not sure what else to say...</p>
<p>Here's what the analog would be:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">trait</span><span class="w"> </span><span class="n">AsRawPtr</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">fn</span> <span class="nf">as_raw_ptr</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>This trait on its own is obviously entirely useless.<br>
If we also bake in an <code>DanIoSafe</code> analog, it'd be something like</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="sd">/// Implementation constraint: the ptr returned by `as_raw_ptr` must be safe to use for as long as</span>
<span class="sd">/// the underlying `self` object exists.</span>
<span class="k">unsafe</span><span class="w"> </span><span class="k">trait</span><span class="w"> </span><span class="n">DanAsRawPtr</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">fn</span> <span class="nf">as_raw_ptr</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>This is not something I ever saw before, hence my strong reaction against it.</p>
<p>In contrast, if we bake in a <code>RalfIoSafe</code> analog, we'd arrive at</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="sd">/// Implementation constraint: the ptr returned by `as_raw_ptr` must be safe to use for as long as</span>
<span class="sd">/// the the lifetime of the `self` reference lasts.</span>
<span class="k">unsafe</span><span class="w"> </span><span class="k">trait</span><span class="w"> </span><span class="n">RalfAsRawPtr</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">fn</span> <span class="nf">as_raw_ptr</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>This trait is <em>entirely equivalent</em> to the following safe trait:</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">trait</span><span class="w"> </span><span class="n">RalfAsBorrow</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">fn</span> <span class="nf">as_raw_ptr</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kp">&amp;</span><span class="kt">u8</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>And that kind of trait, of course, exists all over the place in Rust.<br>
Hence I think this is also the trait we want for FDs.</p>



<a name="238630492"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238630492" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238630492">(May 13 2021 at 14:41)</a>:</h4>
<blockquote>
<p>The idea of introducing borrowing rules without static enforcement seems to me unprecedented. I'm not aware of anything in Rust, or any other language, which works like that.</p>
</blockquote>
<p>You are alluding here to the difference between <code>AsRawFd+RalfIoSafe</code> and <code>AsBorrowedFd</code>? I would indeed prefer the latter; the former is just a hack. But if we add a hack with some "add-on trait", I think it should at least be a principled hack that is equivalent to the "proper" solution (which IMO is <code>AsBorrowedFd</code>), just less type-safe.</p>
<p>FWIW, I would say that your approach also introduces borrowing(-like) rules without static enforcement (that the returned FD must only be used for the lifetime of the object it came from); the only difference between our two approaches is the lifetime of the borrow returned by <code>as_raw_fd</code>.</p>



<a name="238632422"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238632422" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238632422">(May 13 2021 at 14:55)</a>:</h4>
<p>There is a trait which abstracts over all array-like containers though, and you can use it to get an <code>as_ptr()</code> over any such container, in a fully generic and abstract way. It takes one extra step than a dedicated trait method would, but from the user's perspective, it's hazardous in exactly the way <code>DanIoSafe</code> is.</p>



<a name="238632488"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238632488" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238632488">(May 13 2021 at 14:55)</a>:</h4>
<p>What does the trait look like? Not sure if I have seen that.</p>



<a name="238632575"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238632575" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238632575">(May 13 2021 at 14:56)</a>:</h4>
<p>It's <code>std::ops::Index</code>, if I understand correctly. The trait that lets you do <code>&amp;x[..]</code></p>



<a name="238632599"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238632599" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238632599">(May 13 2021 at 14:56)</a>:</h4>
<p>that is the same as chaining <code>RalfAsBorrow</code> with <code>as_ptr</code>, that works just fine -- but then again you are calling <code>as_ptr</code> on a <em>concrete type</em></p>



<a name="238632617"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238632617" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238632617">(May 13 2021 at 14:56)</a>:</h4>
<p>so, not at all what <code>DanIoSafe</code> does, which <em>abstracts over the type</em> on which you call <code>as_raw_fd</code></p>



<a name="238632682"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238632682" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238632682">(May 13 2021 at 14:57)</a>:</h4>
<p>It's not apparent to me whay that matters. It's still an abstraction, meaning you don't need to know the underlying type, and you're at extra risk for accidental mutations</p>



<a name="238632730"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238632730" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238632730">(May 13 2021 at 14:57)</a>:</h4>
<p>it's the difference between</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">trait</span><span class="w"> </span><span class="n">RalfAsBorrow</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">fn</span> <span class="nf">as_raw_ptr</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="kp">&amp;</span><span class="kt">u8</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>and</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">trait</span><span class="w"> </span><span class="n">AsRawPtr</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">fn</span> <span class="nf">as_raw_ptr</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="o">*</span><span class="k">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>



<a name="238632754"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238632754" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238632754">(May 13 2021 at 14:57)</a>:</h4>
<p>not sure how that could possibly <em>not</em> matter^^</p>



<a name="238632813"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238632813" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238632813">(May 13 2021 at 14:58)</a>:</h4>
<p>you <em>do</em> know the underlying type <em>on which <code>as_ptr</code> is called</em></p>



<a name="238632865"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238632865" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238632865">(May 13 2021 at 14:58)</a>:</h4>
<p>But if there are things like <code>Vec::push</code> which invalidate the pointer, you need to know that.</p>



<a name="238632898"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238632898" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238632898">(May 13 2021 at 14:58)</a>:</h4>
<p>so the FD equivalent to your array example would be</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="k">trait</span><span class="w"> </span><span class="n">AsBorrowedFd</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">  </span><span class="k">fn</span> <span class="nf">borrow_fd</span><span class="p">(</span><span class="o">&amp;</span><span class="bp">self</span><span class="p">)</span><span class="w"> </span>-&gt; <span class="nc">BorrowedFd</span><span class="o">&lt;'</span><span class="nb">_</span><span class="o">&gt;</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>
<p>and then call <code>x.borrow_fd().as_raw_fd()</code></p>



<a name="238632965"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238632965" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238632965">(May 13 2021 at 14:59)</a>:</h4>
<p>calling <code>as_raw_fd</code> on a concrete type which can hence easily document the contract around how the resulting FD may be used</p>



<a name="238633083"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238633083" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238633083">(May 13 2021 at 15:00)</a>:</h4>
<p>If you do <code>RalfAsBorrow::as_raw_ptr() as *const u8</code>, the pointer can outlive the reference, if I understand correctly</p>



<a name="238633132"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238633132" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238633132">(May 13 2021 at 15:00)</a>:</h4>
<p>It's obviously not something you want to do often, but it's not invalid</p>



<a name="238633178"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238633178" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238633178">(May 13 2021 at 15:00)</a>:</h4>
<p><span class="user-mention silent" data-user-id="404395">Dan Gohman</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/238632865">said</a>:</p>
<blockquote>
<p>But if there are things like <code>Vec::push</code> which invalidate the pointer, you need to know that.</p>
</blockquote>
<p>yes that is exactly my point for why we want <code>RalfIoSafe</code>, not <code>DanIoSafe</code>. you are arguing my case here, not yours, from all I can see (or I misunderstood the argument).</p>



<a name="238633251"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238633251" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238633251">(May 13 2021 at 15:01)</a>:</h4>
<p><span class="user-mention silent" data-user-id="404395">Dan Gohman</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/238633083">said</a>:</p>
<blockquote>
<p>If you do <code>RalfAsBorrow::as_raw_ptr() as *const u8</code>, the pointer can outlive the reference, if I understand correctly</p>
</blockquote>
<p>it <em>can</em> and then you'll have UB (or at least, you are violating a library contract)</p>



<a name="238633352"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238633352" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238633352">(May 13 2021 at 15:02)</a>:</h4>
<p>same as if you had done <code>&amp;x[..].as_ptr()</code> and then make the ptr outlive <code>x</code></p>



<a name="238633427"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238633427" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238633427">(May 13 2021 at 15:02)</a>:</h4>
<p>I'm saying, I recognize that <code>DanIoSafe</code> isn't an inherently great API. It's really dangerous in exactly the ways you say. I'm just confused about why this wouldn't be an existing concept in Rust.</p>



<a name="238633638"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238633638" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238633638">(May 13 2021 at 15:03)</a>:</h4>
<p>I have never seen a trait like <code>DanAsRawPtr</code>, and it seems hard to imagine when it'd be useful. so maybe the concept <em>exists</em> (I cannot prove non-existence, such proofs are hard), but it is exceedingly rare when compared with <code>RalfAsRawPtr</code>, which (in the form of <code>RalfAsBorrow</code>) exists <em>everywhere</em></p>



<a name="238633766"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238633766" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238633766">(May 13 2021 at 15:04)</a>:</h4>
<p>Is there any documentation you happen to know of documenting something where a raw pointer is expected to be used only within the scope of a reference?</p>



<a name="238633863"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238633863" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238633863">(May 13 2021 at 15:05)</a>:</h4>
<p>doesn't say that?<br>
<a href="https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_ptr">https://doc.rust-lang.org/nightly/std/primitive.slice.html#method.as_ptr</a></p>
<blockquote>
<p>The caller must ensure that the slice outlives the pointer this function returns, or else it will end up pointing to garbage.</p>
</blockquote>



<a name="238633903"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238633903" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238633903">(May 13 2021 at 15:05)</a>:</h4>
<p>this is pretty much the same thing <code>BorrowedFd::as_raw_fd</code> would say</p>



<a name="238634023"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238634023" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238634023">(May 13 2021 at 15:06)</a>:</h4>
<p>Ah, the wording there is a little ambiguous, as to whether it's talking about the memory or the reference</p>



<a name="238634048"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238634048" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238634048">(May 13 2021 at 15:06)</a>:</h4>
<p>The "or else it will end up pointing to garbage" seems to suggest it's thinking about the memory</p>



<a name="238634077"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238634077" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238634077">(May 13 2021 at 15:06)</a>:</h4>
<p>if you have a slice of unknown origin, those are essentially one and the same</p>



<a name="238634136"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238634136" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238634136">(May 13 2021 at 15:06)</a>:</h4>
<p>and when you abstract over the origin with a trait, you by definition have a slice (FD) of unknown origin</p>



<a name="238634143"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238634143" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238634143">(May 13 2021 at 15:06)</a>:</h4>
<p>True, but in the context of that documentation, it might not be</p>



<a name="238634171"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238634171" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238634171">(May 13 2021 at 15:07)</a>:</h4>
<p>yes because its <code>as_ptr</code> <em>on a concrete type</em> :)</p>



<a name="238634188"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238634188" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238634188">(May 13 2021 at 15:07)</a>:</h4>
<p>so it can say more concrete things than a trait can</p>



<a name="238634426"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238634426" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238634426">(May 13 2021 at 15:08)</a>:</h4>
<p>also dont forget about the aliasing rules -- its not enough to just ensure that the memory still exists. so the docs are somewhat incomplete in that regard.</p>



<a name="238635149"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238635149" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238635149">(May 13 2021 at 15:14)</a>:</h4>
<p>Ok, thanks for your explanations here!</p>



<a name="238635186"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238635186" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238635186">(May 13 2021 at 15:14)</a>:</h4>
<p>I'll probably take some time to think through this, and collect any other feedback, before posting an official RFC</p>



<a name="238816270"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/238816270" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#238816270">(May 14 2021 at 19:19)</a>:</h4>
<p>Great, and thanks for spending the time to understand my concerns :)</p>



<a name="240132156"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240132156" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240132156">(May 25 2021 at 01:05)</a>:</h4>
<p>I've now posted the RFC! <a href="https://github.com/rust-lang/rfcs/pull/3128">https://github.com/rust-lang/rfcs/pull/3128</a></p>



<a name="240704615"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240704615" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240704615">(May 29 2021 at 14:20)</a>:</h4>
<p><span class="user-mention" data-user-id="281757">@Jubilee</span> </p>
<blockquote>
<p>soundly invalidate each and every last one of Rust's safety guarantees </p>
</blockquote>
<p>What does that even mean? As far as I am concerned, "not violating Rust's safety guarantees" is the very definition of soundness. "soundly invalidate safety guarantees" is therefore a self-contradicting statement.</p>



<a name="240712059"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240712059" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240712059">(May 29 2021 at 17:27)</a>:</h4>
<p>Alas, the world is full of contradictions, so when and where a contradiction occurs matters. If a program randomly aliases a file, it is harder to predict, because there are many universes where it continues to appear to be a correct program, even though that is technically bogus.</p>
<p>But if a program edits its own memory, consistently, then we can speak with more conviction about that chain of events, even though the point after is hopelessly divergent.</p>



<a name="240712869"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240712869" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240712869">(May 29 2021 at 17:47)</a>:</h4>
<p>hm, I think I still don't get it^^</p>



<a name="240712917"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240712917" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240712917">(May 29 2021 at 17:48)</a>:</h4>
<p>as far as I am concerned, a program that uses <code>/proc/self/mem</code> is not something we even consider as a reasonable / well-behaved program -- the existence of that path is a bug in the underlying target platform that we compile Rust to</p>



<a name="240713813"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240713813" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240713813">(May 29 2021 at 18:08)</a>:</h4>
<p>I view it as more expressing humanity's simultaneous longing for transformation and annihilation. :^)</p>



<a name="240714963"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240714963" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240714963">(May 29 2021 at 18:30)</a>:</h4>
<p>eh... sure ;)</p>



<a name="240723252"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240723252" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Lokathor <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240723252">(May 29 2021 at 21:47)</a>:</h4>
<p>I'm with Ralf: If you reach in to /proc/self/mem and do something that's not a safety failure on Rust's part.</p>



<a name="240767189"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240767189" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240767189">(May 30 2021 at 18:05)</a>:</h4>
<p>Oh my stance is absolutely that it isn't a failure per se <em>of the language</em>. If I said failure I mean strictly in the mechanical sense, e.g. sufficient force was applied to cause a breakage.</p>



<a name="240768040"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240768040" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240768040">(May 30 2021 at 18:28)</a>:</h4>
<p>yeah, I agree something has gone wrong in these programs^^</p>



<a name="240768051"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240768051" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240768051">(May 30 2021 at 18:28)</a>:</h4>
<p>is there any reasonable and realistic way to prevent programs from doing this? like, set some flag in pre-<code>main</code> that tells the kernel "return an error when /proc/self/mem is opened" (with an <code>unsafe fn</code> to un-set the flag, or so)?</p>



<a name="240768129"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240768129" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240768129">(May 30 2021 at 18:31)</a>:</h4>
<p>on linux at least you could create a new filesystem namespace and not mount <code>procfs</code> but that sounds super out-of-scope for what Rust is aiming to be too...</p>



<a name="240768516"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240768516" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240768516">(May 30 2021 at 18:40)</a>:</h4>
<p>yeah that sounds like too heavy a hammer</p>



<a name="240769014"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240769014" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240769014">(May 30 2021 at 18:54)</a>:</h4>
<p>yeah, realistically as a systems language, rust gives up most the options that might be available here.</p>



<a name="240769031"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240769031" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240769031">(May 30 2021 at 18:55)</a>:</h4>
<p>there are also valid reasons to do stuff in procfs, just likely not /proc/self/mem</p>



<a name="240775452"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240775452" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240775452">(May 30 2021 at 21:40)</a>:</h4>
<p>You could theoretically restrict access using something like a seccomp/BPF syscall filter. But you'd also need to cover things like ptrace and process_vm_readv/process_vm_writev, and there are many more where those came from.</p>



<a name="240775455"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240775455" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240775455">(May 30 2021 at 21:40)</a>:</h4>
<p>The Linux syscall interface is not designed to prevent programs from affecting their own address space.</p>



<a name="240775749"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240775749" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240775749">(May 30 2021 at 21:48)</a>:</h4>
<p>the syscall interface isnt our problem, only those syscalls we want to expose to safe code are</p>



<a name="240776462"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240776462" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> nagisa <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240776462">(May 30 2021 at 22:07)</a>:</h4>
<p>This sounds like all of them, though. Like, if a person wanted to make a library which exposed safe interface to some syscall, <code>/proc/self/mem</code> would be the last thing they would think of as a potential soundness hole.</p>



<a name="240784000"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240784000" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> cuviper <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240784000">(May 31 2021 at 01:54)</a>:</h4>
<p>You can do other fun things like double-<code>mmap</code> that bypass memory safety</p>



<a name="240784489"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240784489" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240784489">(May 31 2021 at 02:06)</a>:</h4>
<blockquote>
<p>would be the last thing they would think of as a potential soundness hole.</p>
</blockquote>
<p>Even if I did think of it, I'd ignore it under the precedent that std::fs has decided to ignore it. (It's also an edge case that basically never causes problems unless someone's deliberately trying to cause them)</p>



<a name="240792389"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240792389" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240792389">(May 31 2021 at 05:01)</a>:</h4>
<p>I basically view it as "the goal of Rust is to make it possible to make a program that is well-behaved on an OS that is probably not like any existing OS, because previous systems proglangs were mostly not well-behaved, to a degree that made being well-behaved seem fruitless."</p>



<a name="240792450"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240792450" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240792450">(May 31 2021 at 05:02)</a>:</h4>
<p>i think even non-systems languages let you open /proc/self/mem because at that point it's on you</p>



<a name="240792483"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240792483" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240792483">(May 31 2021 at 05:03)</a>:</h4>
<p>well yeah.<br>
I mostly mean "opening random files that imply absolutely cursed things about how the system expects users to use it is part of the C 'idiom'".</p>



<a name="240792787"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240792787" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240792787">(May 31 2021 at 05:11)</a>:</h4>
<p>yeah, there's definitely a cost to all the weird file wonkiness in unix systems (obligatory <a href="https://www.youtube.com/watch?v=9-IWMbJXoLM">https://www.youtube.com/watch?v=9-IWMbJXoLM</a> for anybody who hasn't seen it)</p>
<div class="youtube-video message_inline_image"><a data-id="9-IWMbJXoLM" href="https://www.youtube.com/watch?v=9-IWMbJXoLM"><img src="https://uploads.zulipusercontent.net/b19f0c9847d4a0695c18dc50dfe1d04426ab8e9c/68747470733a2f2f692e7974696d672e636f6d2f76692f392d49574d624a586f4c4d2f64656661756c742e6a7067"></a></div>



<a name="240792863"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240792863" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Kevin Tran <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240792863">(May 31 2021 at 05:13)</a>:</h4>
<p>does this have anything to do with <code>cap-std</code>?</p>



<a name="240792884"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240792884" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240792884">(May 31 2021 at 05:13)</a>:</h4>
<p>Yeah. It's sort of a tossup whether it's on "C" or "Unix", but since both kinda started as the same thing...<br>
It's a standard of how programming languages are expected to operate, it's completely unworkable for the 21st century, and also it hasn't really been worth refactoring things to actually <strong>not</strong> rely on doing cursed stuff to memory until a few very recent comers like Rust, Haskell, etc.<br>
<span class="user-mention" data-user-id="351526">@Kevin Tran</span> Only indirectly.</p>



<a name="240793310"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240793310" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Kevin Tran <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240793310">(May 31 2021 at 05:22)</a>:</h4>
<p>how are rust and haskell better than something like python and java? all are memory safe</p>



<a name="240793452"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/240793452" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#240793452">(May 31 2021 at 05:26)</a>:</h4>
<p>i dont know that this thread is the right place to discuss that. you could create a new one in general if you want</p>



<a name="241299528"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241299528" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241299528">(Jun 02 2021 at 18:25)</a>:</h4>
<p><span class="user-mention" data-user-id="351526">@Kevin Tran</span> cap-std can be a solution to some forms of the /proc/self/mem problem. If you are opening paths derived from untrusted inputs, and want to keep those paths confined to a particular directory, so they can't get to /proc/self/mem or any of the other "interesting" things in /proc, /dev, /home, or anywhere else, cap-std can do that.</p>



<a name="241300083"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241300083" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241300083">(Jun 02 2021 at 18:29)</a>:</h4>
<p>However, this is a separate topic from I/O safety, because I/O safety is about ensuring that Rust code itself doesn't use forged or dangling resource pointers, while /proc/self/mem and related problems are all about Rust code reaching out to the outside world and causing something to reach back in. While the outcomes may be similar, the potential solutions look very different.</p>



<a name="241342585"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241342585" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241342585">(Jun 03 2021 at 02:30)</a>:</h4>
<p>Yeah, the only reason I remarked on anything re: Rust having unique opportunities here is because if you don't have I/O safety you will have problems addressing the issues of "magic files" that are... a bit too magic. Because if you can't bar use of forged/dangling resources, you will struggle to lock out the magic files, and Python already has somewhat vague semantics around file opening/closing that doesn't use a proper context manager.</p>



<a name="241362757"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241362757" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241362757">(Jun 03 2021 at 08:43)</a>:</h4>
<p><span class="user-mention silent" data-user-id="138448">cuviper</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/240784000">said</a>:</p>
<blockquote>
<p>You can do other fun things like double-<code>mmap</code> that bypass memory safety</p>
</blockquote>
<p>not safely though?</p>



<a name="241362826"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241362826" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> RalfJ <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241362826">(Jun 03 2021 at 08:44)</a>:</h4>
<p><span class="user-mention silent" data-user-id="209168">Thom Chiovoloni</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/240792450">said</a>:</p>
<blockquote>
<p>i think even non-systems languages let you open /proc/self/mem because at that point it's on you</p>
</blockquote>
<p>that's a fair point actually -- people that use this fact against Rust have to also admit that ocaml, Java, Go, Swift, probably even Haskell, ... are all not memory-safe</p>



<a name="241362859"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241362859" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241362859">(Jun 03 2021 at 08:44)</a>:</h4>
<p>In those other languages it may be difficult to get a pointer value to write to though</p>



<a name="241362897"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241362897" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241362897">(Jun 03 2021 at 08:45)</a>:</h4>
<p>except Go I guess</p>



<a name="241370088"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241370088" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Giacomo Stevanato <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241370088">(Jun 03 2021 at 10:02)</a>:</h4>
<p>Isn't there <code>sun.misc.Unsafe.getAddress</code> in java? Although that's has <code>Unsafe</code> in the name so...</p>



<a name="241371769"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241371769" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241371769">(Jun 03 2021 at 10:21)</a>:</h4>
<p>I think all of them have some kind of way to get pointer values but I'm excluding the ones which put such mechanisms behind an API with "unsafe" in the name</p>



<a name="241372474"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241372474" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241372474">(Jun 03 2021 at 10:28)</a>:</h4>
<p>actually, after some investigation it seems you can't convert pointers to integers directly in go without the unsafe package, although you can print pointers and parse the result</p>



<a name="241415996"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241415996" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241415996">(Jun 03 2021 at 16:29)</a>:</h4>
<p><span class="user-mention silent" data-user-id="271719">Mario Carneiro</span> <a href="#narrow/stream/136281-t-lang.2Fwg-unsafe-code-guidelines/topic/I.2FO.20safety/near/241362859">said</a>:</p>
<blockquote>
<p>In those other languages it may be difficult to get a pointer value to write to though</p>
</blockquote>
<p>Hm? That isn't required to do arbitrarily bad things using /proc/self/mem. You just write to the file and it writes to memory — potentially the runtime's memory in languages with a runtime</p>



<a name="241416089"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241416089" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241416089">(Jun 03 2021 at 16:30)</a>:</h4>
<p>Certainly all those languages use pointers in their runtime</p>



<a name="241416925"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241416925" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241416925">(Jun 03 2021 at 16:36)</a>:</h4>
<p>Sure, if you just want to smash and grab then you can just write random things to /proc/self/mem, but if you want to do something targeted like really-safe-transmute then you will want to pass pointers to your own data to /proc/self/mem</p>



<a name="241417137"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241417137" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Mario Carneiro <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241417137">(Jun 03 2021 at 16:38)</a>:</h4>
<p>I'm sure you can also do forensics on the memory layout like a debugger would to find your memory even without being given a hint though</p>



<a name="241419402"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241419402" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Thom Chiovoloni <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241419402">(Jun 03 2021 at 16:55)</a>:</h4>
<p>right, i'm pretty sure if you can find what you want if you do stuff like write some unique data to an array and scan for it</p>



<a name="241442634"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241442634" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241442634">(Jun 03 2021 at 19:45)</a>:</h4>
<p>at some point the without-unsafe API has started to sound even more unsafe than the actually unsafe API.</p>



<a name="241598763"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241598763" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241598763">(Jun 04 2021 at 22:07)</a>:</h4>
<p>Between feedback from various people and my own prototyping, I'm sufficiently happy with the new <code>OwnedFd</code> and <code>BorrowedFd</code> types and their associated traits that I've updated the RFC to propose those, instead of <code>IoSafe</code>.</p>



<a name="241598941"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241598941" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241598941">(Jun 04 2021 at 22:09)</a>:</h4>
<p>It's a bigger change, but it leads to a <em>significantly</em> cleaner API, and with <code>repr(transparent)</code> it can extend safety all the way to the FFI boundary, which is what convinced me that it's  worth it.</p>



<a name="241612713"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241612713" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241612713">(Jun 05 2021 at 03:13)</a>:</h4>
<p>I'm super excited about this!</p>



<a name="241612718"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/241612718" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#241612718">(Jun 05 2021 at 03:13)</a>:</h4>
<p>Thanks for putting in the work.</p>



<a name="242291399"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242291399" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242291399">(Jun 11 2021 at 01:30)</a>:</h4>
<p>As another test, I wrote a bare-metal Linux syscall API with <code>OwnedFd</code>/<code>BorrowedFd</code> in place of <code>c_int</code> for the file descriptors, and as an experiment, ported all the parts of cap-std that currently call into <code>libc</code> to it, and cap-std's tests all pass. I/O safety (and memory safety!) all the way down to the syscalls!</p>



<a name="242297684"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242297684" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Jubilee <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242297684">(Jun 11 2021 at 03:34)</a>:</h4>
<p>nice!</p>



<a name="242383654"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242383654" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242383654">(Jun 11 2021 at 18:17)</a>:</h4>
<p><span class="user-mention" data-user-id="404395">@Dan Gohman</span> That's awesome!</p>



<a name="242383665"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242383665" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242383665">(Jun 11 2021 at 18:17)</a>:</h4>
<p>/me would really love to have that as a crate.</p>



<a name="242383784"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242383784" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242383784">(Jun 11 2021 at 18:18)</a>:</h4>
<p><span class="user-mention" data-user-id="404395">@Dan Gohman</span> I'm currently using a combination of unsafe calls and <code>nix</code> to do calls that aren't available via std, and I'd <em>much</em> rather use an abstraction like <code>BorrowedFd</code> for that.</p>



<a name="242384096"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242384096" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242384096">(Jun 11 2021 at 18:21)</a>:</h4>
<p>Cool, I'll take a look at packaging this up.</p>



<a name="242386440"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242386440" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242386440">(Jun 11 2021 at 18:39)</a>:</h4>
<p><span class="user-mention" data-user-id="239881">@Josh Triplett</span> This will require publishing io-experiment as a crate; do you see any problem with doing that, while the RFC is open?</p>



<a name="242386580"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242386580" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242386580">(Jun 11 2021 at 18:40)</a>:</h4>
<p>/me tries to think of a better crate name than "io-experiment"...</p>



<a name="242392577"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242392577" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242392577">(Jun 11 2021 at 19:30)</a>:</h4>
<p><code>owned-fd</code>?</p>



<a name="242392606"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242392606" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242392606">(Jun 11 2021 at 19:31)</a>:</h4>
<p>Damn, it exists already <span aria-label="laughing" class="emoji emoji-1f606" role="img" title="laughing">:laughing:</span></p>



<a name="242392946"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242392946" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Daniel Henry-Mantilla <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242392946">(Jun 11 2021 at 19:34)</a>:</h4>
<p><code>fd-ownership</code>?</p>



<a name="242393125"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242393125" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242393125">(Jun 11 2021 at 19:36)</a>:</h4>
<p><code>im-not-owned-im-not-owned</code>? :)</p>



<a name="242393176"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242393176" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242393176">(Jun 11 2021 at 19:36)</a>:</h4>
<p>In all seriousness, something like "experimental-owned-fd" seems fine.</p>



<a name="242393205"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242393205" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Josh Triplett <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242393205">(Jun 11 2021 at 19:37)</a>:</h4>
<p>And there's no need to wait for the RFC to close to do that; experimentation on <a href="http://crates.io">crates.io</a> is always fine.</p>



<a name="242676137"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242676137" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242676137">(Jun 15 2021 at 00:44)</a>:</h4>
<p>I went with <code>io-lifetimes</code> <span aria-label="smiley cat" class="emoji emoji-1f63a" role="img" title="smiley cat">:smiley_cat:</span></p>



<a name="242676179"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242676179" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242676179">(Jun 15 2021 at 00:45)</a>:</h4>
<p>I've been porting various projects off of unsafe-io and onto io-lifetimes, and it's working out nicely.</p>



<a name="242676674"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I/O%20safety/near/242676674" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Dan Gohman <a href="https://rust-lang.github.io/zulip_archive/stream/136281-t-lang/wg-unsafe-code-guidelines/topic/I.2FO.20safety.html#242676674">(Jun 15 2021 at 00:54)</a>:</h4>
<p><span class="user-mention" data-user-id="239881">@Josh Triplett</span> I've now published a version of <code>posish</code> with the I/O-safe-down-to-the-syscalls raw-linux syscall support: <a href="https://github.com/bytecodealliance/posish">https://github.com/bytecodealliance/posish</a> . It's early code, but it already passes lots of tests, including Wasmtime's and cap-std's testsuites on x86-64.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>